perm filename PCALL.SAI[PNT,HE]1 blob sn#463375 filedate 1979-08-05 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	ENTRY
C00003 00003	! copycall,editcall
C00005 00004	! 	readcall,renmcall,writecall
C00008 00005	! display: update,arrow,displaycall,redisplaycall,showcall,nodisplaycall
C00014 00006	!	graphcall
C00015 00007	!	deletecall,definecall,notavailcall,exitcall
C00021 00008	!	bailcall,setstatuscall,readmesscall,stopmesscall
C00025 ENDMK
C⊗;
ENTRY;
BEGIN "PCALL"
COMMENT routines which are not available in AL;
DEFINE $PCALL=TRUE,$ALTER_EGO=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;
! copycall,editcall;

	! parses the instructions
		MERGE <frame_id> INTO <frame_id>
		COPY  <frame_id> INTO <frame_id>
	  First is MERGE or COPY;
	! MERGE <frame_id> is now COPY SUBTREE(<frame_id>) ;

INTERNAL PROCEDURE COPYCALL;
	BEGIN
	STRING FR1,FR2,FIRST;
	$HELP←14;
	GTOKEN;
	IF EQU(TOKEN,"SUBTREE") THEN
		BEGIN
		 WORD_READ("("); FR1←IDF_READ;
		 WORD_READ(")"); FIRST←"MERGE";
		END
		ELSE
		BEGIN
		STOKEN←TRUE;
		FR1←IDF_READ;				! reads first frame;
		FIRST←"COPY";
		END;
	WORD_READ("INTO"); 				! reads INTO;
	FR2←IDF_READ;   			! reads second frame;
	SEMICOL_READ; 
	COPYCODE(FIRST,FR1,FR2);
	END;

INTERNAL PROCEDURE EDITCALL(STRING WHAT);
	BEGIN
	STRING VAR;
	NOEXPAND←TRUE;
	IF EQU(WHAT,"EDIT")THEN $HELP←37 ELSE $HELP←38;
	VAR←IDF_READ; 
	SEMICOL_READ;    
	IF EQU(WHAT,"EDIT") THEN EDITCODE(VAR)ELSE RENMCODE(VAR);
	END;
! 	readcall,renmcall,writecall;

IFC #OUTPT THENC
	
INTERNAL PROCEDURE READCALL(BOOLEAN ECHO(TRUE));
	BEGIN
	STRING FILE;           
	IF $COMPILE≠0 THEN ERROR("READ: cannot be inside a block");
	$HELP←34;
	FILE←"DECLAR.AL";				! default value;
	NOEXPAND←TRUE;
	GTOKEN(FALSE);
	IF NOT FINAL
	   THEN BEGIN
		STOKEN←TRUE;FILE←NAMEFILE;SEMICOL_READ;
		END;
	NOEXPAND←FALSE;
        READCODE(FILE,ECHO);
	END;

INTERNAL PROCEDURE WRITCALL;
	BEGIN "A"
	STRING FILE;
	INTEGER NELEMENTS,I;
	RPTR(SYMBOL)ARRAY ELEMENTS[1:20];
	IF $COMPILE≠0 THEN ERROR("WRITE: cannot be inside a block");

	NELEMENTS←0;
	$HELP←31;
	NOEXPAND←TRUE;			! to let through macro names ;
	FILE←$ALFL;			! default values;
	GTOKEN(FALSE);
	IF NOT FINAL 
	   THEN CASE #TOKEN OF
		α	
		[RES_TYPE]
			IF EQU(TOKEN,"INTO") THEN STOKEN←TRUE
			  ELSE IF ¬EQU(TOKEN,"ALL") THEN ERROR("Can't use "&TOKEN&
				" as argument to be saved in a write statement");
		[ID_TYPE]
			DO α
			IF (NELEMENTS←NELEMENTS+1)>21 THEN ERROR("Cant output more than 21 elements in one statement");
			ELEMENTS[NELEMENTS]←TOKENPTR;
			GTOKEN(FALSE);
			IF TOKEN="," THEN GTOKEN
			    ELSE IF FINAL THEN DONE
				ELSE STOKEN←TRUE;
			β UNTIL #TOKEN≠ID_TYPE;

		ELSE ERROR("Can't write out the value of "&TOKEN)
		β;
	GTOKEN(FALSE);
	IF NOT FINAL
	    THEN IF ¬EQU(TOKEN,"INTO") THEN
			ERROR("Need INTO here before putting in file name, but you have got "&token)
		  ELSE FILE←NAMEFILE;
	SEMICOL_READ;
	IF NELEMENTS=0 THEN WRITECODE(FILE,NULL_RECORD)
	    ELSE FOR I←1 STEP 1 UNTIL NELEMENTS DO WRITECODE(FILE,ELEMENTS[I]);

	NOEXPAND ← FALSE;
	END "A";
ENDC
! display: update,arrow,displaycall,redisplaycall,showcall,nodisplaycall;
IFC ¬ #ARROW THENC
INTERNAL SIMPLE PROCEDURE ARROW; ;
ENDC
IFC #DISPL THENC

INTEGER MDISPLAY; ! display mode;
DEFINE  TABLE_DISPLAY=0,
	TYPE_DISPLAY=1,
	SYMBOL_DISPLAY=2,
	NO_DISPLAY=3;

SIMPLE  STRING PROCEDURE DEFAULT;
	RETURN(" "&OLDCMD&CRLF&" "&OLDOBJ&CRLF);

RCLASS SYMBOL_LIST(RPTR(SYMBOL_LIST)NEXT;RPTR(SYMBOL)PTR);
RPTR(SYMBOL_LIST) DISPLAY_LIST;

INTEGER TDISPLAY;
BOOLEAN NDISPLAY;
PROCEDURE DPYELM(STRING S);
	OUTDPW(
"########################### SELECTED VARIABLES ############################"
&crlf&S&crlf&
"###########################################################################",
-3,-2);

PROCEDURE DPYVAR(INTEGER VARTYPE);
	IF NOT $DISPLAYLIST[VARTYPE] THEN
		OUTDPW(
("************************* CURRENT "&$DTYPE[VARTYPE]&"S ***********************************************")
[1 TO 74]&crlf&($DISPLAYLIST[VARTYPE]←DPY_STRING(VARTYPE))&
"***************************************************************************"
,-3,-3);

PROCEDURE DPYSYMS;
BEGIN STRING S;
	RPTR(SYMBOL)SYM;
	RPTR(SYMBOL_LIST)SYL;
	SYL←DISPLAY_LIST;
	S←NULL;
	WHILE SYL≠NULL_RECORD
		DO BEGIN
		S←S&CVSSYM(SYMBOL_LIST:PTR[SYL])&CRLF;
		SYL←SYMBOL_LIST:NEXT[SYL];
		END;
	DPYELM(S);
END;

	! update the display (if $ALLOW=0);

INTERNAL PROCEDURE UPDATE;
	BEGIN INTEGER I;
 	IF $ALLOW>0 THEN RETURN;
	CASE MDISPLAY OF
	    BEGIN
	    [TABLE_DISPLAY]
		BEGIN
		DPYDRAW;
		FOR I←#SC,#VT,#TR,#RT,#FR DO
			IF NOT $DISPLAYLIST[I] THEN $DISPLAYLIST[I]←DPY_STRING(I);
		IFC #OUTPT THENC IF NOT $OULST THEN $OULST←FILE_STRING;ENDC
		$DFLST←DEFAULT;
		OUTDPY;
	 	DPYOUT(1);
		END;
	    [NO_DISPLAY]
		IF NDISPLAY THEN
		BEGIN
		 OUTDPW(
"**************************** P O I N T Y **********************************
DISPLAY SUPPRESSED; TYPE   REDISPLAY  TO GET BACK DISPLAY TABLE
TYPE  DISPLAY SCALARS  TO DISPLAY SCALARS
****************************************************************************
",-3,-2); NDISPLAY←FALSE;
		END;
	    [TYPE_DISPLAY]
		DPYVAR(TDISPLAY);
	    [SYMBOL_DISPLAY]
		DPYSYMS
	    END;
	    ESC_P;
	END;
ENDC

IFC #DISPL THENC

INTERNAL PROCEDURE REDISPLAYCALL;
	BEGIN
	SEMICOL_READ;
	$ALLOW←0;
	TDISPLAY←0;
	MDISPLAY←TABLE_DISPLAY;
	DISPLAY_LIST←NULL_RECORD;
	$SCLST←NULL;
	END;

INTERNAL PROCEDURE NODISPLAYCALL;
	BEGIN
	! SUPPRESS DISPLAY;
	SEMICOL_READ;
	NDISPLAY←TRUE;
	MDISPLAY←NO_DISPLAY;
	DISPLAY_LIST←NULL_RECORD;
	END;

INTERNAL PROCEDURE DISPLAYCALL;
	BEGIN
	INTEGER TT;
	NOEXPAND ← TRUE;
	GTOKEN;
	IF TOKENPTR ≠ NULL_RECORD
	THEN DPYELM(CVSSYM(TOKENPTR))
	ELSE BEGIN
		FOR TT←#MIN STEP 1 UNTIL #MAX DO
		   IF EQU(TOKEN,$DTYPE[TT]) OR EQU(TOKEN,$DTYPE[TT]&"S") THEN DONE;
		IF TT≤#MAX THEN $DISPLAYLIST[TT]←NULL
		   ELSE ERROR("No such data type or identifier: "&TOKEN&CRLF);
		SEMICOL_READ;
		MDISPLAY←TYPE_DISPLAY;
		TDISPLAY←TT;
	    END;
	NOEXPAND ← FALSE;
	END;

INTERNAL PROCEDURE SHOWCALL;
	BEGIN
	RPTR(SYMBOL_LIST)SL1,SL2;
	NOEXPAND ← TRUE;
	SL1←SL2←NEW_RECORD(SYMBOL_LIST);
	DO BEGIN
	    GTOKEN;
	    IF TOKENPTR=NULL_RECORD
		THEN ERROR("SHOW: Need a macro, procedure or variable name after SHOW");
	    SYMBOL_LIST:NEXT[SL2]←SL2←NEW_RECORD(SYMBOL_LIST);
	    SYMBOL_LIST:PTR[SL2]←TOKENPTR;
	    GTOKEN(FALSE);
	    IF TOKEN≠"," AND NOT FINAL THEN ERROR("Need a comma to separate arguments");
	   END UNTIL FINAL;
	NOEXPAND ← FALSE;
	MDISPLAY←SYMBOL_DISPLAY;
	DISPLAY_LIST←SYMBOL_LIST:NEXT[SL1];
	END;
ENDC


!	graphcall;
IFC #GATHER THENC
INTERNAL PROCEDURE GRAPHCALL;
BEGIN
	IF $COMPILE≠0 THEN ERROR("GRAPH: can only be called outside a block");
	IF GRAPTR=NULL_RECORD THEN ERROR("GRAPH: no data currently available");
	BRK_N;
	GRAPH(GRAPHREC:DATA[GRAPTR],
			GRAPHREC:CTLBITS[GRAPTR],
			GRAPHREC:NPNTS[GRAPTR],
			GRAPHREC:SIZE[GRAPTR]);
	GRAPTR←NULL_RECORD;
END;

ENDC
!	deletecall,definecall,notavailcall,exitcall;

INTERNAL PROCEDURE DELETECALL(BOOLEAN QUIET(FALSE));
	BEGIN
	STRING VAR;
	IF $COMPILE≠0 THEN ERROR("DELETE: cannot be invoked inside a block or procedure");

	NOEXPAND ← TRUE;
	GTOKEN(FALSE);
	IF FINAL OR EQU(TOKEN,"ALL")
	   THEN IF QUIET OR EQU(TOKEN,"ALL") THEN RESET
		ELSE  BEGIN	! deletes all the variables;
		STRING ANSWER;
		PRINT("are you sure all variables are to be deleted? ");
		ANSWER←INCHRW;
		PRINT(CRLF);ESC_P;
		IF ANSWER="Y" OR ANSWER="y"
		   THEN	RESET
		   ELSE ABORT1($SEMSG[13]);
		END
	   ELSE BEGIN
		STOKEN←TRUE;
		$ALLOW←$ALLOW+1;
		DO BEGIN "A"
			VAR←IDF_READ;
			KILLVAR(TOKEN,QUIET);
			GTOKEN(FALSE);
			IF TOKEN≠"," AND NOT FINAL
			   THEN BEGIN
			   PRINT($SYNMSG[0],$SYNMSG[25]," OR ");
		           ERROR($SYNMSG[1],$SYNMSG[25] );
		     	   END;
		   END "A"
		UNTIL FINAL;
		$ALLOW←$ALLOW-1;
		END;
	NOEXPAND ← FALSE;
	END;


INTERNAL PROCEDURE DEFINECALL;
   BEGIN RPTR(MACRO) MACPTR; STRING MACNAME; INTEGER DDLCOUNT; STRING BODY,NBODY;
	INTEGER NPARAM;
	NPARAM←0;
	NOEXPAND ← TRUE;
	GTOKEN;
	IF #TOKEN ≠ UNDECLARED_TYPE
		THEN ERROR("MACRO DEFINITION: need undeclared identifier");
	DDLCOUNT ← 0;
	MACPTR ← NEW!RECORD(MACRO);
	MACNAME ← TOKEN;
	GTOKEN;

	IF TOKEN≠"("
	   THEN BEGIN STOKEN←TRUE; MACRO:HEAD[MACPTR]←MACNAME; END
	   ELSE
	    BEGIN "parametered macro"
		RCLASS PLIST(STRING PARAM; RPTR(PLIST) NEXTP);
	    	RPTR(PLIST) TEMP,TEMP0;
		TEMP0←NULL_RECORD;
		DO
		BEGIN "get parameters"
		GTOKEN;
		IF #TOKEN ≠ UNDECLARED_TYPE THEN 
		    ERROR("MACRO DEFINITION: need undeclared token for argument");
		NPARAM←NPARAM+1;
		TEMP←NEW!RECORD(PLIST);
		PLIST:NEXTP[TEMP]←TEMP0;
		PLIST:PARAM[TEMP]←TOKEN;
		TEMP0←TEMP;
		GTOKEN;
		IF TOKEN≠")" AND TOKEN≠"," 
		    THEN ERROR("MACRO DEFINITION: Need comma here");
		END "get parameters" UNTIL TOKEN=")";

		BEGIN
		INTEGER I; STRING ARRAY S[1:NPARAM];
		STRING HEAD; HEAD←")";

		FOR I←NPARAM STEP -1 UNTIL 1 DO
			BEGIN
			HEAD←","&(S[I]←PLIST:PARAM[TEMP])&HEAD;
			TEMP←PLIST:NEXTP[TEMP];
			END;
		MEMORY[LOCATION(S)]↔MEMORY[LOCATION(MACRO:PRLIST[MACPTR])];
		MACRO:HEAD[MACPTR]←MACNAME&"("&HEAD[2 TO ∞];
		END;
		MACRO:NPARAM[MACPTR]←NPARAM;
	    END "parametered macro";
	WORD_READ("=");
	WORD_READ("⊂"); DDLCOUNT ← 1;
	BODY←"⊂";
	
	DO BEGIN
		INTEGER I;
		I←READTILL("⊂⊃");
		BODY←BODY&TOKEN&I;
		IF I="⊂"
		   THEN DDLCOUNT ← DDLCOUNT + 1
		   ELSE DDLCOUNT ← DDLCOUNT - 1;
	   END UNTIL DDLCOUNT=0;

	BODY←BODY[2 TO ∞-1];
	IF NPARAM>0 THEN
	BEGIN
	NBODY←NULL;
	WHILE BODY DO
		BEGIN "process the parameters"
		INTEGER I;
		INTEGER BRCHAR; STRING TTOKEN;
		NBODY←NBODY&SCAN(BODY,$LTTAB,BRCHAR);
		TTOKEN←SCAN(BODY,$NLTTAB,BRCHAR);
		FOR I←1 STEP 1 UNTIL NPARAM
		    DO	IF EQU(MACRO:PRLIST[MACPTR][I],TTOKEN) THEN DONE;
		IF I>NPARAM THEN
			NBODY←NBODY&TTOKEN
			ELSE NBODY←NBODY&DUMMY_DELIM&TTOKEN&DUMMY_DELIM;
		END "process the parameters";
	END ELSE NBODY←BODY;
	MACRO:BODY[MACPTR]←NBODY;
	SEMICOL_READ;
	ENSYM(MACNAME, #MC, MACPTR);
	NOEXPAND ← FALSE;
	$MCLST←NULL;
   END;

INTERNAL PROCEDURE NOTAVAILCALL;
	BEGIN
	PRINT(TOKEN & " " &#VERSION);
	OUTSTR("Will flush this statement"&crlf);
	DO GTOKEN(FALSE) UNTIL FINAL;
	END;

INTERNAL PROCEDURE EXITCALL;
	BEGIN 
	SEMICOL_READ;
	ENDIT;
	END;

!	bailcall,setstatuscall,readmesscall,stopmesscall;

INTERNAL PROCEDURE BAILCALL;
	BAILCODE;
INTERNAL PROCEDURE QBLCALL;
	QBAILCODE;

INTERNAL PROCEDURE SETSTATUSCALL;
	BEGIN
	! this procedure is to set the values of certain POINTY system variables
	in the SAIL part for program control : it takes a VARIABLE and an integer
	and assigns the value of the string to the variable name ;
	INTEGER VARVALUE,I; STRING VARNAME;
	WORD_READ("(");
	NOEXPAND←TRUE;
	GTOKEN;
	VARNAME←TOKEN;
	WORD_READ(",");
	GTOKEN;
	IF #TOKEN≠INT_TYPE THEN ERROR("SETSTATUS: Need integer argument");
	VARVALUE←INTSCAN(TOKEN,I);
	IF EQU(VARNAME,"PPCODE") THEN !PPCODE←VARVALUE
		ELSE IF EQU(VARNAME,"LINE") THEN !LINE←VARVALUE;
	GTOKEN;
	IF TOKEN≠")" THEN ERROR("SETSTATUS: need )");
	NOEXPAND←FALSE;
	SEMICOL_READ;
	END;

INTERNAL PROCEDURE READMESSCALL;
	BEGIN
	SEMICOL_READ;
	PUSHDEVSTACK;
	DEVICE←MESSAGE_X;
	END;

INTERNAL PROCEDURE STOPMESSCALL;
	BEGIN
	SEMICOL_READ;
	$CLNE←$CLINR←NULL;
	POPDEVSTACK;
	END;

END "PCALL";